﻿#include "KSynthesisBase.h"
#include "Tools.h"


KSynthesisBase::KSynthesisBase(const std::string &pSymbol)
	: m_symbolName(pSymbol)
{
	m_verifyTime = Tools::GetCurrentTimeStamp();
}


KSynthesisBase::~KSynthesisBase()
{
}

void KSynthesisBase::SetVerifyTime(time_t pTime)
{
	m_verifyTime = pTime;
}

void KSynthesisBase::UpdateCloseValue(MData::KLineItem &outLastKItem, const MData::KLineItem &pnItem)
{
	outLastKItem.High = std::max(outLastKItem.High, pnItem.High);
	outLastKItem.Low = std::min(outLastKItem.Low, pnItem.Low);
	outLastKItem.Close = pnItem.Close;
	outLastKItem.CloseTime = pnItem.CloseTime;
	outLastKItem.CloseVolume = pnItem.CloseVolume;
}

void KSynthesisBase::GetMinuteKItems(const std::deque<MData::KLineItem> &srcKItems, time_t beginKTime, time_t endKTime, std::deque<MData::KLineItem> &outKItems)
{
	// 找到这个时间的前一根K线和后一根K线
	int preIndex = -1;
	int nxtIndex = -1;
	std::deque<MData::KLineItem> nKItems;
	for (int i = 0; i < srcKItems.size(); ++i)
	{
		const MData::KLineItem &pItem = srcKItems.at(i);
		if (pItem.UpdateTime < beginKTime)
		{
			preIndex = i;
			continue;
		}
		if (pItem.UpdateTime > endKTime)
		{
			nxtIndex = i;
			break;
		}
		nKItems.emplace_back(pItem);
	}
	if (nKItems.empty())
	{
		outKItems.swap(nKItems);
		return;
	}

	if (preIndex >= 0)
	{
		const MData::KLineItem &pItem = srcKItems.at(preIndex);
		// 检查前面一根K线是否是竞价K线
		if (!isSrcKItemFull(pItem))
		{
			if (IsBidingItem(pItem.UpdateTime))
			{
				MData::KLineItem &frontKItem = outKItems.front();
				frontKItem.Open = pItem.Open;
				frontKItem.High = std::max(frontKItem.High, pItem.High);
				frontKItem.Low = std::min(frontKItem.Low, pItem.Low);
			}
		}
	}
	if (nxtIndex >= 0)
	{
		const MData::KLineItem &pItem = srcKItems.at(nxtIndex);
		// 检查下一根K线是否是尾K线
		if (!isSrcKItemFull(pItem))
		{
			MData::KLineItem &backKItem = outKItems.back();
			if (pItem.UpdateTime - backKItem.UpdateTime > 300) // 要合并到上一根
			{
				UpdateCloseValue(backKItem, pItem);
			}
		}
	}

}

bool KSynthesisBase::isSrcKItemFull(const MData::KLineItem &pkItem)
{
	return pkItem.CloseTime - pkItem.UpdateTime > 30;
}

bool KSynthesisBase::IsBidingItem(time_t pItemTime)
{
	return isInRange(pItemTime, 8, 59, 0, 9, 0, 0);
}

bool KSynthesisBase::IsMarketEnd(time_t pItemTime)
{
	if (isInRange(pItemTime, 10, 15, 0, 10, 20, 0))
	{
		return true;
	}
	if (isInRange(pItemTime, 11, 30, 0, 11, 31, 59))
	{
		return true;
	}
	if (isInRange(pItemTime, 15, 00, 0, 15, 01, 59))
	{
		return true;
	}
	return false;
}

bool KSynthesisBase::isInRange(time_t pItemTime, int beginHour, int beginMin, int beginSec, int endHour, int endMin, int endSec)
{
	tm timeStruct = Tools::GetDateTimeFrmStamp(pItemTime);
	tm bidingBegin = timeStruct;
	bidingBegin.tm_hour = beginHour;
	bidingBegin.tm_min = beginMin;
	bidingBegin.tm_sec = beginSec;
	time_t beginStamp = Tools::GetTimeStamp(bidingBegin);
	if (pItemTime < beginStamp)
	{
		return false;
	}

	tm bidingEnd = timeStruct;
	bidingEnd.tm_hour = endHour;
	bidingEnd.tm_min = endMin;
	bidingEnd.tm_sec = endSec;
	time_t endStamp = Tools::GetTimeStamp(bidingEnd);
	if (pItemTime > endStamp)
	{
		return false;
	}
	return true;
}
